package com.zhhh.controller;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wordnik.swagger.annotations.ApiOperation;
import com.zhhh.config.ResultStatus;
import com.zhhh.domain.BMenuTree;
import com.zhhh.domain.BMode;
import com.zhhh.domain.BModeControl;
import com.zhhh.domain.BModeEm;
import com.zhhh.domain.BModeOper;
import com.zhhh.domain.BOrganization;
import com.zhhh.domain.BRole;
import com.zhhh.domain.BRoleModeEm;
import com.zhhh.domain.BRoleModeOper;
import com.zhhh.domain.BUser;
import com.zhhh.domain.ColumnEntity;
import com.zhhh.domain.MenuNode;
import com.zhhh.model.ResultModel;
import com.zhhh.repository.BUserRepository;
import com.zhhh.repository.MenuTreeRepository;
import com.zhhh.repository.ModeControlRepository;
import com.zhhh.repository.ModeEmRepository;
import com.zhhh.repository.ModeOperRepository;
import com.zhhh.repository.ModeRepository;
import com.zhhh.repository.RoleModeEmRepository;
import com.zhhh.repository.RoleModeOperRepository;
import com.zhhh.repository.RoleRepository;
import com.zhhh.repository.SqlDao;
import com.zhhh.utils.CodeUtil;

@RestController
@RequestMapping("/roleprower")
public class RolePowerController {

	@Autowired
	private RoleRepository roleRepository;

	@Autowired
	private ModeRepository modeRepository;

	@Autowired
	private ModeOperRepository modeOperRepository;

	@Autowired
	private ModeEmRepository modeEmRepository;

	@Autowired
	private RoleModeOperRepository roleOperRepository;

	@Autowired
	private ModeControlRepository modeControlRepository;

	@Autowired
	private RoleModeEmRepository roleEmRepository;

	@Autowired
	private BUserRepository uRepository;

	@Autowired
	private SqlDao baseRepository;

	@Autowired
	private MenuTreeRepository menuRepository;

	@RequestMapping(value = "/queryPagePower", method = RequestMethod.POST)
	@ApiOperation(value = "获取登录用户权限")
	public ResponseEntity<ResultModel> getPagePower(@RequestParam String userName, @RequestParam String modeCode) {
		// 获取登录用户对象
		BUser user = uRepository.findByUsername(userName);
		// 获取登录用户角色
		List<Map> list = baseRepository.listBySQL("select role_id from b_user_role where usert_id=" + user.getId());
		// 目前只做单角色处理
		Map<String, Integer> map = list.get(0);
		Integer roleid = map.get("role_id");
		// 获取角色对象包括 其中子集
		BRole role = roleRepository.findById(roleid).get();
		Set<BMode> modes = role.getModes();
		Set<BRoleModeEm> roleEms = role.getRoleEms();
		Set<BRoleModeOper> roleOpers = role.getRoleOpers();
		
		JSONObject roleModeObj = new JSONObject();
		JSONObject modeEmObj = new JSONObject();
		JSONObject modeOperObj = new JSONObject();
	

		for (BMode mode : modes) {
			if (mode.getModeCode().equals(modeCode)) {
				Set<BModeControl> modeControls = mode.getModeControls();
				for (BModeControl modeControl : modeControls) {
					Set<BModeEm> modeEms = modeControl.getModeEms();
					Set<BModeOper> modeOpers = modeControl.getModeOpers();

					for (BModeEm modeEm : modeEms) {
						for (BRoleModeEm roleEm : roleEms) {
							if (modeEm.getEmId().equals(roleEm.getEmId())) {
								modeEm.setRoleModeEm(roleEm);
								modeEmObj.put(modeEm.getEmText(), modeEm);
							}
						}
					}
					modeControl.setModeEms(modeEms);
					for (BModeOper modeOper : modeOpers) {
						for (BRoleModeOper roleOper : roleOpers) {
							if (modeOper.getOperId().equals(roleOper.getOperId())) {
								modeOper.setRoleModeOper(roleOper);
								modeOperObj.put(modeOper.getOperText(), modeOper);
							}
						}
					}
					modeControl.setModeOpers(modeOpers);
				}
				mode.setModeControls(modeControls);
				roleModeObj.put("modeEms", modeEmObj);
				roleModeObj.put("modeOpers", modeOperObj);
				return new ResponseEntity<>(ResultModel.ok(roleModeObj), HttpStatus.OK);
			}
		}
		role.setModes(modes);

		return new ResponseEntity<>(ResultModel.error(ResultStatus.SYS_EXCEPTION), HttpStatus.OK);
	}

	@RequestMapping(value = "/queryMenuTree", method = RequestMethod.POST)
	@ApiOperation(value = "获取登录菜单树")
	public ResponseEntity<ResultModel> queryMenuTree(@RequestParam String userName) {
		// 获取登录用户对象
		BUser user = uRepository.findByUsername(userName);
		// 获取登录用户角色
		List<Map> list = baseRepository.listBySQL("select role_id from b_user_role where usert_id=" + user.getId());
		// 目前只做单角色处理
		Map<String, Integer> map = list.get(0);
		Integer roleid = map.get("role_id");
		// 获取角色对象包括 其中子集
		BRole role = roleRepository.findById(roleid).get();
		// 得到用户的可操作的模块
		Set<BMode> modes = role.getModes();
		List<String> modeIds = new ArrayList<String>();
		for (BMode bMode : modes) {
			modeIds.add(bMode.getId().toString());
		}
		// 根据模块获取用户菜单数据集
		List<BMenuTree> menus = menuRepository.queryMenuTree(modeIds);
		// 菜单树数据集
		List<MenuNode> menuTree = new ArrayList<MenuNode>();
		for (BMenuTree menu : menus) {
			if (menu.getPId() == 0) {
				for (BMode bMode : modes) {
					if (menu.getSModeId().equals(bMode.getId().toString())) {
						MenuNode menuNode = new MenuNode();
						String id = CodeUtil.createUUID();
						menuNode.setId(id);
						menuNode.setModeCode(bMode.getModeCode());
						menuNode.setTitle(menu.getMenuDesc());
						menuNode.setIco("");
						menuNode.setLink(bMode.getUrl());
						menuNode.setModel("0");
						menuNode.setWidth("");
						menuNode.setHeight("");
						menuNode.setPid(menu.getPId());
						menuNode.setMid(menu.getId());
						// 通过递归得到菜单树节点
						menuTree.add(MenuNode.getMenuTreeNode(menus, menuNode, modes));
					}
				}
			}
		}
		return new ResponseEntity<>(ResultModel.ok(menuTree), HttpStatus.OK);
	}

	@RequestMapping(value = "/queryRoleEm", method = RequestMethod.POST)
	@ApiOperation(value = "根据角色编码查询元素权限")
	public ResponseEntity<ResultModel> queryRoleEm(@RequestParam String roleCode, @RequestParam String ctrlId) {
		// BRole findByRoleCode =
		// roleRepository.findByRoleCode(roleCode);//查询出的是这个角色所有元素
		Set<BRoleModeEm> roleEmDatas = roleEmRepository.findByRoleCodeAndCtrlId(roleCode, ctrlId);
		BModeControl findBymodeCode = modeControlRepository.findByctrlId(ctrlId);
		Set<BModeEm> modeEms = findBymodeCode.getModeEms();
		// Set<BRoleModeEm> roleEms = findByRoleCode.getRoleEms();
		for (BModeEm modeEm : modeEms) {
			for (BRoleModeEm roleEm : roleEmDatas) {
				if (modeEm.getEmId().equals(roleEm.getEmId())) {
					modeEm.setRoleModeEm(roleEm);
				}
			}
		}
		return new ResponseEntity<>(ResultModel.ok(modeEms), HttpStatus.OK);
	}

	@RequestMapping(value = "/updateRoleOper", method = RequestMethod.POST)
	@ApiOperation(value = "新增和更新角色操作权限")
	public ResponseEntity<ResultModel> updateRoleOper(@RequestParam String roleCode, @RequestParam String operId,
			@RequestParam Integer ifOper, @RequestParam String ctrlCode, @RequestParam String modeCode) {
		BRole role = roleRepository.findByRoleCode(roleCode);
		BRoleModeOper roleOper = roleOperRepository.findByRoleCodeAndOperId(roleCode, operId);
		if (null == roleOper) {
			roleOper = new BRoleModeOper();
			roleOper.setRoleCode(roleCode);
			roleOper.setIfOper(ifOper);
			roleOper.setOperId(operId);
			roleOper.setCtrlId(ctrlCode);
			roleOper.setModeCode(modeCode);
		} else {
			roleOper.setIfOper(ifOper);
		}
		// 多对一保存是需要对一的一方实例化否则会报如下错误
		// object references an unsaved transient instance - save the transient instance
		// before flushing
		roleOper.setRole(role);
		BRoleModeOper saveOper = roleOperRepository.save(roleOper);

		return new ResponseEntity<>(ResultModel.ok("保存成功"), HttpStatus.OK);
	}

	@RequestMapping(value = "/updateRoleEm", method = RequestMethod.POST)
	@ApiOperation(value = "新增和更新角色元素权限")
	public ResponseEntity<ResultModel> updateRoleEm(@RequestParam String roleCode, @RequestParam String emId,
			@RequestParam Integer ifEnable, @RequestParam String ctrlCode, @RequestParam String modeCode) {
		BRole role = roleRepository.findByRoleCode(roleCode);
		BRoleModeEm roleEm = roleEmRepository.findByRoleCodeAndEmIdAndCtrlCodeAndModeCode(roleCode, emId, ctrlCode,
				modeCode);
		if (null == roleEm) {
			roleEm = new BRoleModeEm();
			roleEm.setRoleCode(roleCode);
			roleEm.setIfEnable(ifEnable);
			roleEm.setEmId(emId);
			roleEm.setCtrlId(ctrlCode);
			roleEm.setModeCode(modeCode);
		} else {
			roleEm.setIfEnable(ifEnable);
		}
		roleEm.setRole(role);
		roleEmRepository.save(roleEm);

		return new ResponseEntity<>(ResultModel.ok("保存成功"), HttpStatus.OK);
	}

	@RequestMapping(value = "/updateRoleEm2", method = RequestMethod.POST)
	@ApiOperation(value = "新增和更新角色元素权限是否显示")
	public ResponseEntity<ResultModel> updateRoleEm2(@RequestParam String roleCode, @RequestParam String emId,
			@RequestParam Integer ifVisible, @RequestParam String ctrlCode, @RequestParam String modeCode) {
		BRole role = roleRepository.findByRoleCode(roleCode);
		Set<BRoleModeEm> roleEms = role.getRoleEms();
		BRoleModeEm roleEm = roleEmRepository.findByRoleCodeAndEmId(roleCode, emId);
		if (null == roleEm) {
			roleEm = new BRoleModeEm();
			roleEm.setRoleCode(roleCode);
			roleEm.setIfVisible(ifVisible);
			roleEm.setEmId(emId);
			roleEm.setCtrlId(ctrlCode);
			roleEm.setModeCode(modeCode);
		} else {
			roleEm.setIfVisible(ifVisible);
			for (BRoleModeEm em : roleEms) {
				if (em.getId() == roleEm.getId()) {
					roleEms.remove(em);
					roleEms.add(roleEm);
					break;
				}
			}
		}

		roleEms.add(roleEm);
		role.setRoleEms(roleEms);
		roleRepository.save(role);

		return new ResponseEntity<>(ResultModel.ok("保存成功"), HttpStatus.OK);
	}

	@RequestMapping(value = "/queryModeOperOrEm", method = RequestMethod.POST)
	@ApiOperation(value = "查询模块操作或者元素信息")
	public ResponseEntity<ResultModel> queryModeOperOrEm(@RequestParam String id, @RequestParam String type) {
		Object result = null;
		if ("3".equals(type)) {
			result = modeOperRepository.findById(Integer.parseInt(id));
		} else if ("4".equals(type)) {
			result = modeEmRepository.findById(Integer.parseInt(id));
		}
		return new ResponseEntity<>(ResultModel.ok(result), HttpStatus.OK);
	}

	@RequestMapping(value = "/addRoleMode", method = RequestMethod.POST)
	@ApiOperation(value = "增加角色模块")
	public ResponseEntity<ResultModel> addRoleMode(@RequestParam Integer id, @RequestParam("jsonStr") String listJSON) {
		BRole role = roleRepository.findById(id).get();
		List<BMode> modes = JSON.parseArray(listJSON, BMode.class);
		for (int i = 0; i < modes.size(); i++) {
			BMode mode = modes.get(i);
			role.getModes().add(mode);
			mode.getRoles().add(role);
			modeRepository.save(mode);
			/*============初始化授权数据===============*/
			Set<BModeControl> modeControls = mode.getModeControls();
			for (BModeControl bModeControl : modeControls) {
				Set<BModeOper> modeOpers = bModeControl.getModeOpers();
				Set<BRoleModeOper> roleModeOpers = role.getRoleOpers();
				for (BModeOper modeOper : modeOpers) {
					BRoleModeOper bRoleModeOper = new BRoleModeOper();
					bRoleModeOper.setCtrlId(bModeControl.getCtrlId());
					bRoleModeOper.setIfOper(1);
					bRoleModeOper.setModeCode(mode.getModeCode());
					bRoleModeOper.setRoleCode(role.getRoleCode());
					bRoleModeOper.setOperId(modeOper.getOperId());
					bRoleModeOper.setRole(role);
					BRoleModeOper save = roleOperRepository.save(bRoleModeOper);
					roleModeOpers.add(save);
				}
				role.setRoleOpers(roleModeOpers);
				Set<BModeEm> modeEms = bModeControl.getModeEms();
				Set<BRoleModeEm> roleModeEms = role.getRoleEms();
				for (BModeEm modeEm : modeEms) {
					BRoleModeEm bRoleModeEm = new BRoleModeEm();
					bRoleModeEm.setCtrlId(bModeControl.getCtrlId());
					bRoleModeEm.setEmId(modeEm.getEmId());
					bRoleModeEm.setIfEnable(1);
					bRoleModeEm.setIfVisible(1);
					bRoleModeEm.setModeCode(mode.getModeCode());
					bRoleModeEm.setRoleCode(role.getRoleCode());
					bRoleModeEm.setRole(role);
					BRoleModeEm save = roleEmRepository.save(bRoleModeEm);
					roleModeEms.add(save);
				}
				role.setRoleEms(roleModeEms);
			}
			/*============初始化授权数据===============*/
		}
		roleRepository.save(role);

		/*
		 * 多对多 如果启用了双向关联 两种对象必须都进行保存一次，中间表才会新增数据建立关联关系
		 */
		BRole roleResult = roleRepository.findById(role.getId()).get();
		return new ResponseEntity<>(ResultModel.ok(roleResult), HttpStatus.OK);
	}

	@RequestMapping(value = "/deleteRoleMode", method = RequestMethod.POST)
	@ApiOperation(value = "删除角色模块")
	public ResponseEntity<ResultModel> deleteRoleMode(@RequestParam Integer rid, @RequestParam Integer mid) {
		BRole role = roleRepository.findById(rid).get();
		BMode mode = modeRepository.findById(mid).get();
		role.getModes().remove(mode);
		mode.getRoles().remove(role);
		roleRepository.save(role);
		modeRepository.save(mode);
		/*
		 * 多对多 如果启用了双向关联 两种对象必须都进行保存一次，中间表才会新增数据建立关联关系
		 */
		BRole roleResult = roleRepository.findById(role.getId()).get();
		return new ResponseEntity<>(ResultModel.ok(roleResult), HttpStatus.OK);
	}

	@RequestMapping(value = "/queryRoleUserAll", method = RequestMethod.POST)
	@ApiOperation(value = "查询一个角色下所有用户")
	public ResponseEntity<ResultModel> queryRoleUserAll(@RequestParam Integer id) {
		BRole role = roleRepository.findById(id).get();
		return new ResponseEntity<>(ResultModel.ok(role), HttpStatus.OK);
	}

	@RequestMapping(value = "/addRoleUser", method = RequestMethod.POST)
	@ApiOperation(value = "增加角色人员")
	public ResponseEntity<ResultModel> addRoleUser(@RequestParam Integer id, @RequestParam("jsonStr") String listJSON) {
		BRole role = roleRepository.findById(id).get();
		List<BUser> users = JSON.parseArray(listJSON, BUser.class);
		for (int i = 0; i < users.size(); i++) {
			BUser user = users.get(i);
			role.getUsers().add(user);
			user.getRoles().add(role);
			uRepository.save(user);
		}
		roleRepository.save(role);
		BRole roleInfo = roleRepository.findById(id).get();
		return new ResponseEntity<>(ResultModel.ok(roleInfo), HttpStatus.OK);
	}

	@RequestMapping(value = "/deleteRoleUser", method = RequestMethod.POST)
	@ApiOperation(value = "删除角色人员")
	public ResponseEntity<ResultModel> deleteRoleUser(@RequestParam Integer rid, @RequestParam Integer uid) {
		BRole role = roleRepository.findById(rid).get();
		BUser user =  uRepository.findById(uid).get();
		role.getModes().remove(user);
		user.getRoles().remove(role);
		roleRepository.save(role);
		uRepository.save(user);
		/*
		 * 多对多 如果启用了双向关联 两种对象必须都进行保存一次，中间表才会新增数据建立关联关系
		 */
		BRole roleResult = roleRepository.findById(role.getId()).get();
		return new ResponseEntity<>(ResultModel.ok(roleResult), HttpStatus.OK);
	}
}
